<style>
    .node {
        stroke: #fff;
        stroke-width: 1.5px;
        cursor: pointer;
    }
    .node.artifact {
        fill: #ff5733;
    }
    .node.story {
        fill: #33ff57;
    }
    .node.meaning {
        fill: #3357ff;
    }
    .node.shape {
        fill: #ff9933;
    }
    .link {
        stroke: #999;
        stroke-opacity: 0.6;
        stroke-width: 1px;
    }
    #graphSection svg {
        border: 1px solid #eee;
        background-color: #fafafa;
    }
    .node-label {
        font-size: 12px;
        pointer-events: none;
    }
    .tooltip {
        position: absolute;
        padding: 8px;
        background: white;
        border: 1px solid #ddd;
        border-radius: 4px;
        pointer-events: none;
        font-size: 12px;
        box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }
    .node-group {
        cursor: pointer;
    }
    .node.qixing {
        fill: #ff7f0e;
        stroke: #d66b0d;
        stroke-width: 2px;
    }
    .node.artifact {
        fill: #ff5733;
        stroke: #fff;
        stroke-width: 1.5px;
    }
    .node.pattern {
        fill: #9c27b0;
        stroke: #7b1fa2;
        stroke-width: 2px;
    }
</style>

<div id="graphSection" class="content-section container-fluid py-6">
    <div class="row">
        <div class="col-8">
            <div class="bg-white rounded-2xl shadow-xl p-6 mb-6 fade-in">
                <div class="d-flex justify-content-between align-items-center mb-4">
                    <h2 class="text-2xl font-bold text-gray-800">
                        <i class="fas fa-project-diagram me-2"></i>知识图谱
                    </h2>
                    <div class="flex items-center space-x-3">
                        <div class="relative">
                            <input class="form-control pl-10 pr-4 py-2 rounded-xl border-2 border-gray-200 focus:border-green-500 focus:outline-none transition duration-300" 
                                id="searchInput" type="search" placeholder="搜索文物..." aria-label="Search">
                            <i class="fas fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
                        </div>
                        <button onclick="search()" 
                            class="btn btn-success rounded-xl px-4 py-2 bg-gradient-to-r from-green-500 to-green-600 hover:from-green-600 hover:to-green-700 text-white shadow-lg hover:shadow-xl transition duration-300">
                            <i class="fas fa-search me-2"></i>搜索
                        </button>
                    </div>
                </div>
                <div class="d-flex justify-content-between align-items-center mb-4">
                    <div class="d-flex align-items-center">
                        <select id="queryType" class="form-select me-3 rounded-xl border-2 border-gray-200" onchange="loadData()">
                            <option value="artifact-meaning">文物-意义关系</option>
                            <option value="artifact-story">文物-故事关系</option>
                            <option value="artifact-qixing">文物-器型关系</option>
                            <option value="artifact-pattern">文物-纹样关系</option>
                            <option value="artifact-all">全部关系</option>
                        </select>
                        <select id="limitCount" class="form-select rounded-xl border-2 border-gray-200" onchange="loadData()">
                            <option value="10">显示10条</option>
                            <option value="50">显示50条</option>
                            <option value="0">显示全部</option>
                        </select>
                    </div>
                </div>
                <div class="relative rounded-xl overflow-hidden border-2 border-gray-100 bg-gray-50">
                    <svg width="100%" height="600"></svg>
                </div>
            </div>
        </div>
        <div class="col-4">
            <div class="bg-white rounded-2xl shadow-xl p-6 fade-in sticky top-6">
                <h3 class="text-xl font-bold mb-4 text-gray-800">
                    <i class="fas fa-info-circle me-2"></i>文物详情
                </h3>
                <div id="detailsContent" class="prose max-w-none">
                    <div class="text-gray-500 text-center py-8">
                        <i class="fas fa-hand-pointer mb-3 text-3xl"></i>
                        <p>点击图谱中的节点查看详细信息</p>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<div id="tooltip" class="tooltip" style="display: none;"></div>

<script>
function loadData() {
    const queryType = document.getElementById('queryType').value;
    const limit = parseInt(document.getElementById('limitCount').value) || 0;
    
    // 使用新的API端点获取数据
    fetch(`/api/data/${queryType}?limit=${limit}`)
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                console.log('Received data:', data.data); // 添加调试日志
                if (queryType === 'artifact-qixing') {
                    renderQixingGraph(data.data);
                } else if (queryType === 'artifact-pattern') {
                    renderPatternGraph(data.data);
                } else if (queryType === 'artifact-meaning' || queryType === 'artifact-story' || queryType === 'artifact-all') {
                    renderGraph(data.data);
                }
            }
        })
        .catch(error => console.error('Error fetching the data:', error));
}

function renderGraph(data) {
    const nodes = [];
    const links = [];
    const nodeMap = new Map();
    
    data.forEach(item => {
        if (!nodeMap.has(item.artifact_code)) {
            nodes.push({
                id: item.artifact_code,
                name: item.artifact_name,
                type: 'artifact'
            });
            nodeMap.set(item.artifact_code, true);
        }
        
        if (item.meaning_name) {
            if (!nodeMap.has(item.meaning_name)) {
                nodes.push({
                    id: item.meaning_name,
                    name: item.meaning_name,
                    type: 'meaning'
                });
                nodeMap.set(item.meaning_name, true);
            }
            
            links.push({
                source: item.artifact_code,
                target: item.meaning_name,
                type: 'has_meaning'
            });
        }
        
        if (item.story_name) {
            if (!nodeMap.has(item.story_name)) {
                nodes.push({
                    id: item.story_name,
                    name: item.story_name,
                    type: 'story'
                });
                nodeMap.set(item.story_name, true);
            }
            
            links.push({
                source: item.artifact_code,
                target: item.story_name,
                type: 'has_story'
            });
        }
    });
    
    const svg = d3.select('#graphSection svg');
    svg.selectAll('*').remove();
    
    const width = svg.node().getBoundingClientRect().width;
    const height = svg.node().getBoundingClientRect().height;
    
    const simulation = d3.forceSimulation(nodes)
        .force('link', d3.forceLink(links).id(d => d.id).distance(100))
        .force('charge', d3.forceManyBody().strength(-300))
        .force('center', d3.forceCenter(width / 2, height / 2))
        .force('collision', d3.forceCollide().radius(30));
    
    const link = svg.append('g')
        .selectAll('line')
        .data(links)
        .enter().append('line')
        .attr('class', 'link');
    
    const node = svg.append('g')
        .selectAll('g')
        .data(nodes)
        .enter().append('g')
        .attr('class', 'node-group');
    
    node.append('circle')
        .attr('class', d => `node ${d.type}`)
        .attr('r', 8)
        .call(d3.drag()
            .on('start', dragstarted)
            .on('drag', dragged)
            .on('end', dragended));
    
    node.append('text')
        .attr('class', 'node-label')
        .attr('dy', 4)
        .text(d => d.name.length > 15 ? d.name.substring(0, 15) + '...' : d.name)
        .attr('text-anchor', 'middle');
    
    node.on('mouseover', function(event, d) {
        const tooltip = d3.select('#tooltip');
        let content = `<strong>${d.name}</strong><br>类型: ${d.type}`;
        
        tooltip.html(content)
            .style('left', (event.pageX + 10) + 'px')
            .style('top', (event.pageY - 10) + 'px')
            .style('display', 'block');
    })
    .on('mouseout', function() {
        d3.select('#tooltip').style('display', 'none');
    })
    .on('click', function(event, d) {
        showDetails(d);
    });
    
    simulation.on('tick', () => {
        link
            .attr('x1', d => d.source.x)
            .attr('y1', d => d.source.y)
            .attr('x2', d => d.target.x)
            .attr('y2', d => d.target.y);
        
        node
            .attr('transform', d => `translate(${d.x},${d.y})`);
    });
    
    function dragstarted(event) {
        if (!event.active) simulation.alphaTarget(0.3).restart();
        event.subject.fx = event.subject.x;
        event.subject.fy = event.subject.y;
    }
    
    function dragged(event) {
        event.subject.fx = event.x;
        event.subject.fy = event.y;
    }
    
    function dragended(event) {
        if (!event.active) simulation.alphaTarget(0);
        event.subject.fx = null;
        event.subject.fy = null;
    }
}

function renderQixingGraph(data) {
    const svg = d3.select('#graphSection svg');
    svg.selectAll('*').remove();
    
    const width = svg.node().getBoundingClientRect().width;
    const height = svg.node().getBoundingClientRect().height;
    
    // 预处理数据，确保所有节点都被正确创建
    const processedData = {
        nodes: [],
        links: []
    };
    
    // 创建节点映射
    const nodeMap = new Map();
    
    // 首先处理所有的器型节点
    data.nodes.forEach(node => {
        if (node.type === 'qixing') {
            nodeMap.set(node.id, node);
            processedData.nodes.push(node);
        }
    });
    
    // 然后处理所有的文物节点
    data.nodes.forEach(node => {
        if (node.type === 'artifact') {
            // 确保节点ID不包含特殊字符
            const safeId = node.id.replace(/['"]/g, '_');
            const safeNode = {
                ...node,
                id: safeId,
                originalId: node.id  // 保存原始ID用于显示
            };
            nodeMap.set(safeId, safeNode);
            processedData.nodes.push(safeNode);
        }
    });
    
    // 处理链接，确保使用安全的节点ID
    data.links.forEach(link => {
        const sourceId = link.source.id || link.source;
        const targetId = link.target.id || link.target;
        
        // 使用安全的ID创建链接
        const safeSourceId = sourceId.replace(/['"]/g, '_');
        const safeTargetId = targetId.replace(/['"]/g, '_');
        
        if (nodeMap.has(safeSourceId) && nodeMap.has(safeTargetId)) {
            processedData.links.push({
                source: safeSourceId,
                target: safeTargetId,
                type: link.type
            });
        }
    });
    
    // 按器型分组
    const qixingGroups = new Map();
    processedData.nodes.forEach(node => {
        if (node.type === 'qixing') {
            qixingGroups.set(node.id, {
                qixing: node,
                artifacts: []
            });
        }
    });
    
    // 将文物添加到对应的器型组
    processedData.links.forEach(link => {
        const sourceNode = nodeMap.get(link.source);
        const targetNode = nodeMap.get(link.target);
        if (targetNode && targetNode.type === 'qixing') {
            const group = qixingGroups.get(targetNode.id);
            if (group && sourceNode) {
                group.artifacts.push(sourceNode);
            }
        }
    });
    
    // 设置力导向图的参数
    const simulation = d3.forceSimulation(processedData.nodes)
        .force('link', d3.forceLink(processedData.links)
            .id(d => d.id)
            .distance(d => {
                // 增加器型节点与文物节点之间的距离
                if (d.source.type === 'qixing' || d.target.type === 'qixing') {
                    return 120;
                }
                return 80;
            }))
        .force('charge', d3.forceManyBody()
            .strength(d => d.type === 'qixing' ? -800 : -200))
        .force('center', d3.forceCenter(width / 2, height / 2))
        .force('collision', d3.forceCollide().radius(d => d.type === 'qixing' ? 50 : 20))
        .force('radial', d3.forceRadial(
            d => d.type === 'qixing' ? 0 : 200,
            width / 2,
            height / 2
        ).strength(0.8));
    
    // 创建连线
    const link = svg.append('g')
        .selectAll('line')
        .data(processedData.links)
        .enter().append('line')
        .attr('class', 'link')
        .style('stroke-width', d => {
            const sourceNode = nodeMap.get(d.source.id || d.source);
            const targetNode = nodeMap.get(d.target.id || d.target);
            return (sourceNode && sourceNode.type === 'qixing') || 
                   (targetNode && targetNode.type === 'qixing') ? 2 : 1;
        });
    
    // 创建节点组
    const node = svg.append('g')
        .selectAll('g')
        .data(processedData.nodes)
        .enter().append('g')
        .attr('class', 'node-group');
    
    // 添加圆形节点
    node.append('circle')
        .attr('class', d => `node ${d.type}`)
        .attr('r', d => d.type === 'qixing' ? 25 : 8)
        .style('fill', d => d.type === 'qixing' ? '#ff7f0e' : '#ff5733')
        .style('stroke', d => d.type === 'qixing' ? '#d66b0d' : '#fff')
        .style('stroke-width', d => d.type === 'qixing' ? 3 : 1.5)
        .call(d3.drag()
            .on('start', dragstarted)
            .on('drag', dragged)
            .on('end', dragended));
    
    // 添加文本标签
    node.append('text')
        .attr('class', 'node-label')
        .attr('dy', d => d.type === 'qixing' ? -30 : 15)
        .text(d => {
            const displayName = d.originalId || d.name;  // 使用原始ID进行显示
            if (d.type === 'qixing') {
                return displayName;
            } else {
                return displayName.length > 15 ? displayName.substring(0, 15) + '...' : displayName;
            }
        })
        .attr('text-anchor', 'middle')
        .style('font-size', d => d.type === 'qixing' ? '14px' : '12px')
        .style('font-weight', d => d.type === 'qixing' ? 'bold' : 'normal');
    
    // 添加交互事件
    node.on('mouseover', function(event, d) {
        const tooltip = d3.select('#tooltip');
        const displayName = d.originalId || d.name;
        let content = `<strong>${displayName}</strong><br>类型: ${d.type === 'qixing' ? '器型' : '文物'}`;
        
        if (d.type === 'qixing') {
            const group = qixingGroups.get(d.id);
            content += `<br>相关文物数量: ${group ? group.artifacts.length : 0}`;
        }
        
        tooltip.html(content)
            .style('left', (event.pageX + 10) + 'px')
            .style('top', (event.pageY - 10) + 'px')
            .style('display', 'block');
        
        // 高亮相关连线和节点
        const relatedNodes = new Set();
        if (d.type === 'qixing') {
            const group = qixingGroups.get(d.id);
            if (group) {
                group.artifacts.forEach(artifact => relatedNodes.add(artifact.id));
            }
        } else {
            processedData.links.forEach(l => {
                if (l.source.id === d.id || l.source === d.id) relatedNodes.add(l.target);
                if (l.target.id === d.id || l.target === d.id) relatedNodes.add(l.source);
            });
        }
        
        node.style('opacity', n => relatedNodes.has(n.id) || n.id === d.id ? 1 : 0.1);
        link.style('opacity', l => 
            (l.source.id === d.id || l.source === d.id || 
             l.target.id === d.id || l.target === d.id) ? 1 : 0.1
        ).style('stroke-width', l => 
            (l.source.id === d.id || l.source === d.id || 
             l.target.id === d.id || l.target === d.id) ? 3 : 1
        );
    })
    .on('mouseout', function() {
        d3.select('#tooltip').style('display', 'none');
        node.style('opacity', 1);
        link.style('opacity', 0.6).style('stroke-width', d => {
            const sourceNode = nodeMap.get(d.source.id || d.source);
            const targetNode = nodeMap.get(d.target.id || d.target);
            return (sourceNode && sourceNode.type === 'qixing') || 
                   (targetNode && targetNode.type === 'qixing') ? 2 : 1;
        });
    })
    .on('click', function(event, d) {
        showDetails({
            ...d,
            name: d.originalId || d.name  // 使用原始ID显示详情
        });
    });
    
    // 更新力导向图
    simulation.on('tick', () => {
        link
            .attr('x1', d => d.source.x)
            .attr('y1', d => d.source.y)
            .attr('x2', d => d.target.x)
            .attr('y2', d => d.target.y);
        
        node
            .attr('transform', d => `translate(${d.x},${d.y})`);
    });
    
    // 拖拽相关函数
    function dragstarted(event) {
        if (!event.active) simulation.alphaTarget(0.3).restart();
        event.subject.fx = event.subject.x;
        event.subject.fy = event.subject.y;
    }
    
    function dragged(event) {
        event.subject.fx = event.x;
        event.subject.fy = event.y;
    }
    
    function dragended(event) {
        if (!event.active) simulation.alphaTarget(0);
        event.subject.fx = null;
        event.subject.fy = null;
    }
}

function renderPatternGraph(data) {
    console.log('Rendering pattern graph with data:', data);
    const svg = d3.select('#graphSection svg');
    svg.selectAll('*').remove();
    
    const width = svg.node().getBoundingClientRect().width;
    const height = svg.node().getBoundingClientRect().height;
    
    // 确保数据格式正确
    const processedData = {
        nodes: data.nodes || [],
        links: data.links || []
    };
    
    // 创建节点映射和分组
    const nodeMap = new Map();
    const artifactGroups = new Map();
    
    // 首先处理所有节点
    processedData.nodes.forEach(node => {
        nodeMap.set(node.id, node);
        if (node.type === 'artifact') {
            artifactGroups.set(node.id, {
                center: node,
                patterns: []
            });
        }
    });
    
    // 然后处理链接，将纹样节点分配到对应的文物组
    processedData.links.forEach(link => {
        const sourceNode = nodeMap.get(link.source);
        const targetNode = nodeMap.get(link.target);
        
        if (sourceNode && targetNode) {
            if (sourceNode.type === 'artifact' && targetNode.type === 'pattern') {
                const group = artifactGroups.get(sourceNode.id);
                if (group) {
                    group.patterns.push(targetNode);
                }
            }
        }
    });
    
    // 设置力导向图的参数
    const simulation = d3.forceSimulation(processedData.nodes)
        .force('link', d3.forceLink(processedData.links)
            .id(d => d.id)
            .distance(d => {
                // 文物节点之间的距离较大，文物与纹样之间的距离较小
                const source = nodeMap.get(d.source.id || d.source);
                const target = nodeMap.get(d.target.id || d.target);
                if (source && target) {
                    if (source.type === 'artifact' && target.type === 'artifact') {
                        return 300; // 文物节点之间的距离
                    } else {
                        return 100; // 文物与纹样之间的距离
                    }
                }
                return 150;
            }))
        .force('charge', d3.forceManyBody()
            .strength(d => d.type === 'artifact' ? -1000 : -30)) // 文物节点斥力更大
        .force('center', d3.forceCenter(width / 2, height / 2))
        .force('collision', d3.forceCollide()
            .radius(d => d.type === 'artifact' ? 60 : 20))
        .force('radial', d3.forceRadial(
            d => d.type === 'artifact' ? 0 : 100,
            width / 2,
            height / 2
        ).strength(d => d.type === 'artifact' ? 0.2 : 0.1));

    // 创建连线
    const link = svg.append('g')
        .selectAll('line')
        .data(processedData.links)
        .enter().append('line')
        .attr('class', 'link')
        .style('stroke-width', 1)
        .style('stroke-opacity', 0.6);
    
    // 创建节点组
    const node = svg.append('g')
        .selectAll('g')
        .data(processedData.nodes)
        .enter().append('g')
        .attr('class', 'node-group');
    
    // 添加圆形节点
    node.append('circle')
        .attr('class', d => `node ${d.type}`)
        .attr('r', d => d.type === 'artifact' ? 30 : 8)
        .style('fill', d => d.type === 'artifact' ? '#ff5733' : '#9c27b0')
        .style('stroke', d => d.type === 'artifact' ? '#fff' : '#7b1fa2')
        .style('stroke-width', d => d.type === 'artifact' ? 3 : 1.5)
        .call(d3.drag()
            .on('start', dragstarted)
            .on('drag', dragged)
            .on('end', dragended));
    
    // 添加文本标签
    node.append('text')
        .attr('class', 'node-label')
        .attr('dy', d => d.type === 'artifact' ? -35 : 20)
        .text(d => {
            const text = d.name || '';
            return text.length > 15 ? text.substring(0, 15) + '...' : text;
        })
        .attr('text-anchor', 'middle')
        .style('font-size', d => d.type === 'artifact' ? '14px' : '12px')
        .style('font-weight', d => d.type === 'artifact' ? 'bold' : 'normal');
    
    // 添加交互事件
    node.on('mouseover', function(event, d) {
        const tooltip = d3.select('#tooltip');
        let content = `<strong>${d.name}</strong><br>类型: ${d.type === 'artifact' ? '文物' : '纹样'}`;
        
        if (d.type === 'artifact') {
            const group = artifactGroups.get(d.id);
            if (group) {
                content += `<br>纹样数量: ${group.patterns.length}`;
            }
            if (d.period) {
                content += `<br>年代: ${d.period}`;
            }
        } else if (d.type === 'pattern') {
            if (d.pattern_type) {
                content += `<br>纹样类型: ${d.pattern_type}`;
            }
            if (d.pattern_meaning) {
                content += `<br>含义: ${d.pattern_meaning}`;
            }
        }
        
        tooltip.html(content)
            .style('left', (event.pageX + 10) + 'px')
            .style('top', (event.pageY - 10) + 'px')
            .style('display', 'block');
        
        // 高亮相关连线和节点
        const relatedNodes = new Set();
        processedData.links.forEach(l => {
            if (l.source.id === d.id || l.source === d.id) {
                relatedNodes.add(l.target.id || l.target);
            }
            if (l.target.id === d.id || l.target === d.id) {
                relatedNodes.add(l.source.id || l.source);
            }
        });
        
        node.style('opacity', n => relatedNodes.has(n.id) || n.id === d.id ? 1 : 0.1);
        link.style('opacity', l => 
            (l.source.id === d.id || l.source === d.id || 
             l.target.id === d.id || l.target === d.id) ? 1 : 0.1
        ).style('stroke-width', l => 
            (l.source.id === d.id || l.source === d.id || 
             l.target.id === d.id || l.target === d.id) ? 2 : 1
        );
    })
    .on('mouseout', function() {
        d3.select('#tooltip').style('display', 'none');
        node.style('opacity', 1);
        link.style('opacity', 0.6).style('stroke-width', 1);
    })
    .on('click', showDetails);
    
    // 更新力导向图
    simulation.on('tick', () => {
        link
            .attr('x1', d => d.source.x)
            .attr('y1', d => d.source.y)
            .attr('x2', d => d.target.x)
            .attr('y2', d => d.target.y);
        
        node
            .attr('transform', d => `translate(${d.x},${d.y})`);
    });
    
    // 拖拽相关函数
    function dragstarted(event) {
        if (!event.active) simulation.alphaTarget(0.3).restart();
        event.subject.fx = event.subject.x;
        event.subject.fy = event.subject.y;
    }
    
    function dragged(event) {
        event.subject.fx = event.x;
        event.subject.fy = event.y;
    }
    
    function dragended(event) {
        if (!event.active) simulation.alphaTarget(0);
        event.subject.fx = null;
        event.subject.fy = null;
    }
}

function showDetails(node) {
    const detailsContent = document.getElementById('detailsContent');
    let content = `<h4 class="text-lg font-semibold mb-3">${node.name}</h4>`;
    
    if (node.type === 'shape') {
        content += `
            <p class="mb-2"><strong>类型:</strong> 器型</p>
            ${node.feature ? `<p class="mb-2"><strong>特点:</strong> ${node.feature}</p>` : ''}
        `;
    } else if (node.type === 'artifact') {
        content += `
            <p class="mb-2"><strong>类型:</strong> 文物</p>
            <p class="mb-2"><strong>编号:</strong> ${node.id}</p>
            ${node.period ? `<p class="mb-2"><strong>年代:</strong> ${node.period}</p>` : ''}
        `;
    } else if (node.type === 'pattern') {
        content += `
            <p class="mb-2"><strong>类型:</strong> 纹样</p>
            ${node.pattern_type ? `<p class="mb-2"><strong>纹样类型:</strong> ${node.pattern_type}</p>` : ''}
            ${node.pattern_meaning ? `<p class="mb-2"><strong>含义解读:</strong> ${node.pattern_meaning}</p>` : ''}
            ${node.pattern_image_sam ? `
                <div class="mb-2">
                    <strong>算法提取纹样图:</strong><br>
                    <img src="${node.pattern_image_sam}" alt="算法提取纹样图" class="mt-2 max-w-full h-auto rounded">
                </div>` : ''}
            ${node.pattern_image_manual ? `
                <div class="mb-2">
                    <strong>手工绘制纹样图:</strong><br>
                    <img src="${node.pattern_image_manual}" alt="手工绘制纹样图" class="mt-2 max-w-full h-auto rounded">
                </div>` : ''}
        `;
    } else if (node.type === 'meaning') {
        content += `
            <p class="mb-2"><strong>类型:</strong> 意义</p>
            <p class="mb-2"><strong>编号:</strong> ${node.id}</p>
        `;
    } else if (node.type === 'story') {
        content += `
            <p class="mb-2"><strong>类型:</strong> 故事</p>
            <p class="mb-2"><strong>编号:</strong> ${node.id}</p>
        `;
    }
    
    detailsContent.innerHTML = content;
}
</script>